package com.mycompany.j2eem.recommend;

import com.mycompany.j2eem.Entity.bean.PictureObjectBean;
import com.mycompany.j2eem.Entity.bean.RecommendItem;
import com.mycompany.j2eem.Entity.bean.TagObjectBean;
import com.mycompany.j2eem.Entity.bean.UserBean;
import com.mycompany.j2eem.Mapper.wrjmapper.RecommendationMapper;

import java.util.*;

/**
 * @author wurj
 * @time 2019/4/16 14:11
 * @description
 */

public class ItemCF {


    RecommendationMapper recommendationMapper;

    //图片列表
    public List<PictureObjectBean> pictures = new ArrayList<>();
    //用户列表
    public List<UserBean> users = new ArrayList<>();
    //标签列表
    public List<TagObjectBean> tags =new ArrayList<>();


//    //用户喜欢图片情况
//    private Integer[][] allUserPicLikesList = {
//            {1, 1, 1, 0, 1, 0, 0},
//            {0, 1, 1, 0, 0, 1, 0},
//            {1, 0, 1, 1, 1, 1, 1},
//            {1, 1, 1, 1, 1, 0, 0},
//            {1, 1, 0, 1, 0, 1, 1}
//    };

    private  Integer[][] allUserLikesList;

    //    //所有被喜欢过的图片
//    private   Integer[][] allLiked=new Integer[allUserLikesList[0].length][allUserLikesList.length];

    //所有被喜欢过的图片
    private   Integer[][] allLiked;


    //待推荐实体的相似度
    private HashMap<String, Double> readyToRecommendSim = null;

    //实体的相似度
    private HashMap<Integer, Object> sim = null;

    //目标用户的index
    private Integer targetUserIndex = null;

    //目标客户曾经喜欢过的图片
    private List<Integer> targetUserLikedPic = null;

    //推荐列表
    private List<Map.Entry<Integer, Object>> recommendList = null;

    List<RecommendItem> recommendItems;

    String userName;


    public ItemCF(boolean isTag, RecommendationMapper recommendationMapper) {
        this.recommendationMapper=recommendationMapper;
        //获取全部图片信息
        recommendItems=recommendationMapper.getAllMessage();

        System.out.println("size="+recommendItems.size());
        if(recommendItems.size()!=0){
            //根据标记选择是进行tag还是pic的推荐
            if (isTag){
                //构造user对象
                users=constructUsers(recommendItems);
                  System.out.println("users"+users.size());
                //构造Tag对象
                tags=constructTags(recommendItems);
                 System.out.println("tag"+tags.size());

                allUserLikesList =initTagLikeMatrix(users.size(), tags.size(), tags,users);
                allLiked =new Integer[allUserLikesList[0].length][allUserLikesList.length];
            }else {
                //构造user对象
                users=constructUsers(recommendItems);
                System.out.println("users"+users.size());
                //构造picture对象
                pictures=constructPic(recommendItems);
                System.out.println("pic"+pictures.size());

                allUserLikesList =initPicLikeMatrix(users.size(),pictures.size(),pictures,users);
                System.out.println("大小："+allUserLikesList[0].length);
                allLiked =new Integer[allUserLikesList[0].length][allUserLikesList.length];
            }
        }else {
            return;
        }
    }

    private List<TagObjectBean> constructTags(List<RecommendItem> recommendItems) {
        List<TagObjectBean> tagBeans=new ArrayList<>();
        for (int i=0;i<recommendItems.size();i++){
            String tagId=recommendationMapper.getTagNameIdByPicId(recommendItems.get(i).getPicture_id());
            String tagName=recommendationMapper.getTagName(tagId);
            for (int j=0;j<=i;j++){
                if (tagBeans.size()!=0){
                    TagObjectBean tagBean=tagBeans.get(i);
                    if (!tagBean.getTagId().equals(tagId)){
                        tagBeans.add(new TagObjectBean(i,tagId,tagName));
                    }
                }else {
                    tagBeans.add(new TagObjectBean(i,tagId,tagName));
                }
            }
        }
        return tagBeans;
    }

    private List<PictureObjectBean> constructPic(List<RecommendItem> recommendItems) {
        List<PictureObjectBean> pictureBeans=new ArrayList<>();
        for (int i=0;i<recommendItems.size();i++){
            String picId=recommendItems.get(i).getPicture_id();
            String picPath=recommendationMapper.getPath(picId);
            for (int j=0;j<=i;j++){
                if (pictureBeans.size()!=0){
                    PictureObjectBean pictureBean=pictureBeans.get(i);
                    if (!pictureBean.getPictureId().equals(picId)){
                        pictureBeans.add(new PictureObjectBean(i,picId,picPath));     //index，picID,picPath
                    }
                }else {
                    pictureBeans.add(new PictureObjectBean(i,picId,picPath));     //index，picID,picPath
                }
            }
        }
        return pictureBeans;
    }

    public List<UserBean> constructUsers( List<RecommendItem> recommendItems){
        List<UserBean> userBeans=new ArrayList<>();
        for (int i=0;i<recommendItems.size();i++){
            System.out.println(recommendItems.get(i));
            String accountId=recommendItems.get(i).getAccount_id();
            String picId=recommendItems.get(i).getPicture_id();
            String tagIdName=recommendationMapper.getTagName(picId);
            System.out.println("accountId "+accountId+" picId "+picId+" tagId "+recommendationMapper.getTagNameIdByTagName(tagIdName));
            for (int j=0;j<=i;j++){
                System.out.println("循环");
                if (userBeans.size()!=0){
                    UserBean userBean=userBeans.get(j);
                    if (!userBean.getUserId().equals(accountId)||userBean.getUserId().equals(null)){
                        System.out.println("执行第一个");
                        userBeans.add(new UserBean(i,accountId,recommendationMapper.getUserName(accountId)));//在当前的index，用户id，名字
                        userBeans.get(j).addLikePic(picId);
                        userBeans.get(j).addLikeTag(recommendationMapper.getTagNameIdByPicId(tagIdName));
                    }else {
                        System.out.println("执行第二个");
                        userBean.addLikePic(picId);
                        userBean.addLikeTag(recommendationMapper.getTagNameIdByTagName(tagIdName));
                    }
                }else {
                    System.out.println("第二个大If");
                    userBeans.add(new UserBean(i,accountId,recommendationMapper.getUserName(accountId)));//在当前的index，用户id，名字
                    userBeans.get(j).addLikePic(picId);
                    userBeans.get(j).addLikeTag(recommendationMapper.getTagNameIdByPicId(tagIdName));
                }
            }
        }
        return userBeans;
    }

    public Integer[][] initPicLikeMatrix(int people, int pictures, List<PictureObjectBean> pictureBeans, List<UserBean> userBeans){
        Integer[][] allLikeMatrix=new Integer[people][pictures];
        for (int i=0;i<people;i++){
            for (int j=0;j<pictures;j++){
                if (userBeans.get(i).getLikeId().contains(pictureBeans.get(j).getPictureId())){
                    allLikeMatrix[i][j]=1;
                }else {
                    allLikeMatrix[i][j]=0;
                }
            }
        }
        return allLikeMatrix;
    }



    public Integer[][] initTagLikeMatrix(int people, int tags, List<TagObjectBean> tagBeans, List<UserBean> userBeans){
        Integer[][] allLikeMatrix=new Integer[people][tags];
        for (int i=0;i<people;i++){
            for (int j=0;j<tags;j++){
                if (userBeans.get(i).getTagId().contains(tagBeans.get(j).getTagId())){
                    allLikeMatrix[i][j]=1;
                }else {
                    allLikeMatrix[i][j]=0;
                }
            }
        }
        return allLikeMatrix;
    }

    //获取全部推荐实体列表
    public void getAllRecommendPics() {
        sim = new HashMap<>();
        for (int i = 0; i < targetUserLikedPic.size() - 1; i++) {
            for (int j = i + 1; j < targetUserLikedPic.size(); j++) {
                Object sim = null;
                if (targetUserLikedPic.get(i).equals(1) && targetUserLikedPic.get(j).equals(0) &&
                        (readyToRecommendSim.get(i + "" + j) != null || readyToRecommendSim.get(j + "" + i) != null)) {
                    sim = readyToRecommendSim.get(i + "" + j) != null ? readyToRecommendSim.get(i + "" + j) : readyToRecommendSim.get(j + "" + i);
                    this.sim.put(j, sim);
                } else if (targetUserLikedPic.get(i).equals(0) && targetUserLikedPic.get(j).equals(1) &&
                        (readyToRecommendSim.get(i + "" + j) != null || readyToRecommendSim.get(j + "" + i) != null)) {
                    sim = readyToRecommendSim.get(i + "" + j) != null ? readyToRecommendSim.get(i + "" + j) : readyToRecommendSim.get(j + "" + i);
                    this.sim.put(i, sim);
                }
            }
        }

        recommendList = new ArrayList<Map.Entry<Integer, Object>>(sim.entrySet());
        Collections.sort(recommendList, new Comparator<Map.Entry<Integer, Object>>() {
            @Override
            public int compare(Map.Entry<Integer, Object> o1, Map.Entry<Integer, Object> o2) {
                return o1.getValue().toString().compareTo(o2.getValue().toString());
            }
        });

        System.out.println("待推荐的实体列表" + recommendList);

    }


    //计算两图片之间的相似度
    public void calculateSim() {
        converRow2Vec();
        readyToRecommendSim = new HashMap<>();
        for (int i = 0; i < allLiked.length - 1; i++) {
            for (int j = i + 1; j < allLiked.length; j++) {
                readyToRecommendSim.put(i + "" + j, calculate2EntitySim(allLiked[i], allLiked[j]));
            }
        }

        System.out.println("实体相似度" + readyToRecommendSim);
    }


    //Jaccard相似度计算
    public Double calculate2EntitySim(Integer[] pic1, Integer[] pic2) {
        float sum = 0;
        for (int i = 0; i < pic1.length; i++) {
            sum += Math.pow(pic1[i] - pic2[i], 2);
        }
        return Math.sqrt(sum);
    }


    //行转列
    public void converRow2Vec() {
        for (int i = 0; i < allUserLikesList[0].length; i++) {
            for (int j = 0; j < allUserLikesList.length; j++) {
                allLiked[i][j] = allUserLikesList[j][i];
            }
        }
        System.out.println("实体对象行转列" + Arrays.deepToString(allLiked));
    }

    //查找用户位置
    public Integer getUesrIndex(String user) {
        if (user == null) {
            return null;
        }
        for (int i = 0; i < users.size(); i++) {
            if (user.equals(users.get(i).getNickName())) {
                return i;
            }
        }
        return null;
    }

    public List<PictureObjectBean> getPictures() {
        return pictures;
    }

    public void setPictures(List<PictureObjectBean> pictures) {
        this.pictures = pictures;
    }

    public List<UserBean> getUsers() {
        return users;
    }

    public void setUsers(List<UserBean> users) {
        this.users = users;
    }

    public Integer[][] getAllUserPicLikesList() {
        return allUserLikesList;
    }

    public void setAllUserPicLikesList(Integer[][] allUserPicLikesList) {
        this.allUserLikesList = allUserPicLikesList;
    }

    public Integer[][] getAllLiked() {
        return allLiked;
    }

    public void setAllLiked(Integer[][] allLiked) {
        this.allLiked = allLiked;
    }

    public HashMap<String, Double> getReadyToRecommendSim() {
        return readyToRecommendSim;
    }

    public void setReadyToRecommendSim(HashMap<String, Double> readyToRecommendSim) {
        this.readyToRecommendSim = readyToRecommendSim;
    }

    public HashMap<Integer, Object> getSim() {
        return sim;
    }

    public void setSim(HashMap<Integer, Object> sim) {
        this.sim = sim;
    }

    public Integer getTargetUserIndex() {
        return targetUserIndex;
    }

    public void setTargetUserIndex(Integer targetUserIndex) {
        this.targetUserIndex = targetUserIndex;
    }

    public List<Integer> getTargetUserLikedPic() {
        return targetUserLikedPic;
    }

    public void setTargetUserLikedPic(List<Integer> targetUserLikedPic) {
        this.targetUserLikedPic = targetUserLikedPic;
    }

    public List<Map.Entry<Integer, Object>> getRecommendList() {
        return recommendList;
    }

    public void setRecommendList(List<Map.Entry<Integer, Object>> recommendList) {
        this.recommendList = recommendList;
    }

    public List<TagObjectBean> getTags() {
        return tags;
    }

    public void setTags(List<TagObjectBean> tags) {
        this.tags = tags;
    }

    public Integer[][] getAllUserLikesList() {
        return allUserLikesList;
    }

    public void setAllUserLikesList(Integer[][] allUserLikesList) {
        this.allUserLikesList = allUserLikesList;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public List<RecommendItem> getRecommendItems() {
        return recommendItems;
    }

    public void setRecommendItems(List<RecommendItem> recommendItems) {
        this.recommendItems = recommendItems;
    }

}
